#pragma once

/**
 * @brief 第一版本：支持默认构造，并能判断是否为空。
 *
 * 主要新增：
 *   - 存储指针与删除器成员。
 *   - 默认构造时指针置空。
 *   - 提供 get() 与 operator bool() 访问接口。
 */
template <typename T, typename Deleter = void(*)(T*)>
class UniquePtr {
public:
    using pointer      = T*;
    using element_type = T;
    using deleter_type = Deleter;

    /**
     * @brief 默认构造函数。
     *
     * 将托管指针置为 nullptr；删除器暂时也置为 nullptr，
     * 后续会用到默认删除函数，先在此留空。
     */
    // 在 C++20 中，如果构造函数是 constexpr，并且内部操作也都是常量表达式可用的，那么你就可以在编译期构造该对象。
    constexpr UniquePtr() noexcept
        : ptr_(nullptr)
        , deleter_(nullptr) {}

    /// 获取当前托管的裸指针
    pointer get() const noexcept {
        return ptr_;
    }

    /**
     * @brief 显式的 bool 转换。
     *
     * 当 ptr_ 非空时返回 true，表示当前持有资源。
     */
    // explicit：保护接口，避免隐式转换带来的潜在意外，同时保留在布尔条件中的可读写法。
    explicit operator bool() const noexcept {
        return ptr_ != nullptr;
    }

private:
    pointer      ptr_;     ///< 当前托管的裸指针，尚未进行默认删除器初始化
    deleter_type deleter_; ///< 删除器对象，后续迭代会赋予默认值
};